import os
import re
from typing import Dict, Any
from docx import Document
from docx.shared import Inches
import subprocess
import tempfile
import logging

logger = logging.getLogger(__name__)

class DocxConverter:
    """Word文档转换器"""
    
    def to_markdown(self, docx_path: str, options: Dict[str, Any] = None) -> str:
        """
        将Word文档转换为Markdown
        
        Args:
            docx_path: Word文档路径
            options: 转换选项
            
        Returns:
            Markdown内容
        """
        if not options:
            options = {}
        
        doc = Document(docx_path)
        content = []
        
        # 添加文件名作为标题（如果选项中指定）
        if options.get('add_title', False):
            filename = os.path.splitext(os.path.basename(docx_path))[0]
            content.append(f'# {filename}')
            content.append('')
        
        # 处理文档段落
        for paragraph in doc.paragraphs:
            text = paragraph.text.strip()
            if not text:
                continue
            
            # 处理标题
            if paragraph.style.name.startswith('Heading'):
                level = self._extract_heading_level(paragraph.style.name)
                content.append('#' * level + ' ' + text)
                content.append('')
            else:
                # 处理普通段落
                formatted_text = self._format_paragraph(paragraph, options)
                if formatted_text:
                    content.append(formatted_text)
                    content.append('')
        
        # 处理表格
        for table in doc.tables:
            table_md = self._convert_table_to_markdown(table)
            if table_md:
                content.extend(table_md)
                content.append('')
        
        return '\n'.join(content)
    
    def to_pdf(self, docx_path: str, output_path: str, options: Dict[str, Any] = None):
        """
        将Word文档转换为PDF
        
        Args:
            docx_path: Word文档路径
            output_path: 输出PDF路径
            options: 转换选项
        """
        try:
            # 使用LibreOffice进行转换
            cmd = [
                'libreoffice',
                '--headless',
                '--convert-to', 'pdf',
                '--outdir', os.path.dirname(output_path),
                docx_path
            ]
            
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
            
            if result.returncode != 0:
                raise Exception(f"LibreOffice转换失败: {result.stderr}")
            
            # LibreOffice会生成与输入文件同名的PDF文件
            generated_pdf = os.path.join(
                os.path.dirname(output_path),
                os.path.splitext(os.path.basename(docx_path))[0] + '.pdf'
            )
            
            # 如果生成的文件名与目标文件名不同，则重命名
            if generated_pdf != output_path and os.path.exists(generated_pdf):
                os.rename(generated_pdf, output_path)
                
        except subprocess.TimeoutExpired:
            raise Exception("Word转PDF超时")
        except FileNotFoundError:
            # 如果没有LibreOffice，尝试使用python-docx2pdf
            try:
                from docx2pdf import convert
                convert(docx_path, output_path)
            except ImportError:
                raise Exception("需要安装LibreOffice或docx2pdf库来支持Word转PDF")
    
    def _extract_heading_level(self, style_name: str) -> int:
        """提取标题级别"""
        match = re.search(r'(\d+)', style_name)
        return int(match.group(1)) if match else 1
    
    def _format_paragraph(self, paragraph, options: Dict[str, Any]) -> str:
        """格式化段落文本"""
        text = paragraph.text.strip()
        
        # 处理段落内的格式
        formatted_text = ""
        for run in paragraph.runs:
            run_text = run.text
            
            # 处理粗体
            if run.bold:
                run_text = f"**{run_text}**"
            
            # 处理斜体
            if run.italic:
                run_text = f"*{run_text}*"
            
            formatted_text += run_text
        
        # 处理换行
        if options.get('preserve_line_breaks', True):
            # 将硬换行转换为Markdown换行
            formatted_text = re.sub(r'\n', '  \n', formatted_text)
        
        return formatted_text.strip()
    
    def _convert_table_to_markdown(self, table) -> list:
        """将Word表格转换为Markdown表格"""
        if not table.rows:
            return []
        
        markdown_table = []
        
        # 处理表头
        header_row = table.rows[0]
        headers = [cell.text.strip() for cell in header_row.cells]
        markdown_table.append('| ' + ' | '.join(headers) + ' |')
        markdown_table.append('| ' + ' | '.join(['---'] * len(headers)) + ' |')
        
        # 处理数据行
        for row in table.rows[1:]:
            cells = [cell.text.strip() for cell in row.cells]
            # 确保单元格数量与表头一致
            while len(cells) < len(headers):
                cells.append('')
            markdown_table.append('| ' + ' | '.join(cells[:len(headers)]) + ' |')
        
        return markdown_table 